#ifndef DYNAMIC_PROGRAMMING_SMART_HEADER
#define DYNAMIC_PROGRAMMING_SMART_HEADER

#include "animalwrapper.h"

// This class does the same things as DynamicProgramming
// but uses a definitely more compact way to compute
// the same results
class DynamicProgrammingSmart {
	public:
		DynamicProgrammingSmart();
		// Policy evaluator, returns number of iterations on the states' values
		int policyEvaluation( double discount, bool iteration );
		// Value Iteration, returns number of iterations on the states' values
		int valueIteration( double discount );
		// Policy iterator, returns best policy for the environment
		int policyIteration( double discount );
		// Used to fetch particular state values
		double getStateValue(int a, int b, int c, int d);
		// Used to fetch particular state-action policy values
		double getStatePolicy(int a, int b, int c, int d, int e);
	private:
		// Resets stateValues and stateValuesBackup to zero matrices
		void resetStateValues();
		// Reverts to random policy
		void resetStatePolicy();
		// Copies the content of stateValues into stateValuesBackup
		void updateStateValuesBackup();
		// Computes the summatory of the values of the states that the predator can reach if it follows predAction
		double getNextStatesSum( int predX, int predY, int predAction, double discount );
		// Evaluator of a particular state value following a random policy
		double stateValuePE(int predX, int predY, double discount );
		// Evaluator of a particular state value following a greedy policy
		double stateValueVI(int predX, int predY, double discount );
		// Reports the probability that the prey moves in a given way from the agents' position
		double getPreyActionProbability( int predX, int predY, int preyMove );
		// Sets the position inside the compact system of the cell reached following a from x, y
		void getNextCell( int x, int y, int a, int * x2, int * y2 );
		// Translates action a into the equivalent action given the current orientation
		int getOrientedAction( int a );
		// Given that the prey is in 5,5, sets the predator position inside the compact system
		void normalizePredatorPosition( int x, int y, int * x2, int * y2 );

		// Keeps track of all the state values
		double stateValues[21];
		// State values backup, used for computations
		double stateValuesBackup[21];
		// Policy values
		double statePolicy[21][5];
		// Current orientation ( used only to fetch data )
		int orientation;
};

#endif
